Due to advancements in processing technology, complex integrated circuits (ICs) can be designed at various levels of abstraction. Using a hardware description language (HDL), circuits can be designed at the gate level, the register transfer level (RTL), and higher logical levels. When designing using an HDL, the design is often structured in a modular manner. The designer describes a module in terms of the behavior of a system, the behavior describing the generation and propagation of signals through modules of combinatorial logic from one set of registers to another set of registers. HDLs provide a rich set of constructs to describe the functionality of a module. Modules may be combined and augmented to form even higher-level modules.
Prior to implementation, an HDL-based design can be simulated to determine whether the design will function as required. Wasted manufacturing costs due to faulty design may thereby be avoided. Numerous tools are available for simulating circuit designs including, for example, high-level modeling systems (HLMS) and HDL simulators.
Simulation of an HDL-based design comprises a compilation phase and a runtime simulation phase. In the compilation phase, HDL source code is input, analyzed, and elaborated to generate executable simulation code. In the runtime simulation phase, the code generated in the compilation phase is executed by a simulation engine to simulate the design.
From a user perspective, HDL simulators work by compiling the HDL-based design once, and then executing the compiled design many times during the runtime phase. Therefore, the runtime performance of HDL simulators is of critical importance, and may be more important than compile time performance.
An HDL-based design is a hierarchy of modules whose behavior is described by HDL processes. When the HDL-based design is written in VHDL, an HDL process corresponds to either a VHDL process, a concurrent signal assignment, or a concurrent assertion. When the HDL-based design is written in the Verilog language, an HDL process corresponds to either a Verilog always block, an initial block, an assign statement, or a gate. Procedure calls may or may not be regarded as HDL processes. From a hardware perspective, the HDL processes represent hardware that responds to changes in inputs. For example, a change to an output of one circuit may trigger responses in multiple circuits having inputs coupled to the output.
HDL simulators schedule execution of HDL statements such that global variables or signals input to the HDL statements are properly updated and race conditions between concurrent HDL statements are avoided. Simulation of HDL processes is performed over a number of simulation cycles. Each simulation cycle begins with updates to values of nets. Each net, which may be a VHDL signal or a Verilog net, represents values transmitted on a wire of a circuit design. For ease of reference, VHDL signals and Verilog nets may be referred to as either signals or nets, and such terms are used interchangeably herein. Each update to a net may trigger a number of processes which model how a hardware implementation of the design would respond. Processes dependent on the updated nets are scheduled and executed in a delta cycle.
Depending on the circuit design, a net may be changed or updated by the output of multiple processes. Each process output that may affect a net is referred to as a driver. If a process has several statements assigning values to the same net, only one driver for the net is created per process. The value of the driver is computed from all the values assigned to that signal in the process, according to predefined language rules. A net that has at most one driver for each bit is said to be singly-driven. A net that has several drivers on the same set of bits is said to be multiply-driven.
When a net is driven by multiple drivers, a value of the net is determined when nets are updated at runtime using a resolution function. The value computed by the resolution function is referred to as the resolved value, and the resolved value will be assigned as the new value of the net. The process of computing the new value from the driver values of a net is called driver resolution. The resolution function can be standard, defined by the HDL language itself or, for VHDL, can be user defined.
In addition, nets may model a level of strength of a driven logic signal. Signal strength levels may be modeled for some nets and not for others. Further, Verilog allows individual nets to be forced to a specified valued by a process during simulation. Forcing is performed using a force construct that effectively nullifies the effect of any other values driven on the signal and instead overrides the signal with a value specified by the force until a release construct reconfigures the net to again be affected by the driver values.
Previous methods for simulation of HDL circuit designs compile the designs and generate simulation code on a module-by-module basis, with no regard to different dependencies, strengths, and forcing characteristics of different nets. Rather, such characteristics are determined and processed dynamically at simulation runtime. As a result, the simulation code for modeling of nets generated by the previous compilation methods must be general enough to be capable of handling all net characteristics including forcing and strength modeling. Large data structures of pointers are created to store the values, strengths, forced status, and dependencies of drivers and nets. These data structures require a significant amount of memory to store data values and pointers between the data structures.
The complex data structures of the prior approaches are computationally inefficient for nets of the circuit design that do not model all characteristics. Furthermore, when data structures are dynamically created, the memory needed to store the various data values is allocated at runtime. Due to the dynamic allocation of memory, data needed for various computations performed regularly during simulation may be stored in separate locations of memory. As a result, the simulation processes may have to separately and repeatedly access a large number of different locations of memory to retrieve all the required data. These separate memory accesses by the resolution function can significantly impact simulation runtime.
One or more embodiments may address one or more of the above issues.